/*!
 * 智能错误修复器 - 针对性修复编译错误
 */

use anyhow::{Result, Context};
use crate::project_builder::CompileError;

/// 智能修复器 - 只修复错误相关的代码片段
pub struct SmartFixer;

impl SmartFixer {
    /// 提取错误周围的代码上下文（前后各 50 行）
    pub fn extract_error_context(
        content: &str,
        error: &CompileError,
        context_lines: usize,
    ) -> Result<(String, usize, usize)> {
        let lines: Vec<&str> = content.lines().collect();
        
        if let Some(error_line) = error.line_number {
            let error_idx = (error_line as usize).saturating_sub(1);
            
            // 计算上下文范围
            let start = error_idx.saturating_sub(context_lines);
            let end = (error_idx + context_lines + 1).min(lines.len());
            
            let context = lines[start..end].join("\n");
            Ok((context, start + 1, end))
        } else {
            // 如果没有行号，返回前 200 行
            let preview_lines = lines.iter().take(200).cloned().collect::<Vec<_>>().join("\n");
            Ok((preview_lines, 1, 200.min(lines.len())))
        }
    }
    
    /// 合并修复后的代码片段回原文件
    pub fn merge_fixed_context(
        original: &str,
        fixed_context: &str,
        start_line: usize,
        end_line: usize,
    ) -> Result<String> {
        let mut lines: Vec<String> = original.lines().map(|s| s.to_string()).collect();
        let fixed_lines: Vec<String> = fixed_context.lines().map(|s| s.to_string()).collect();
        
        let start_idx = start_line.saturating_sub(1);
        let end_idx = end_line.min(lines.len());
        
        // 替换错误区域的代码
        lines.splice(start_idx..end_idx, fixed_lines);
        
        Ok(lines.join("\n"))
    }
    
    /// 将多个错误按行号分组（避免重叠修复）
    pub fn group_errors_by_proximity(
        errors: &[CompileError],
        proximity_threshold: usize,
    ) -> Vec<Vec<CompileError>> {
        let mut sorted_errors = errors.to_vec();
        sorted_errors.sort_by_key(|e| e.line_number.unwrap_or(0));
        
        let mut groups = Vec::new();
        let mut current_group = Vec::new();
        let mut last_line = 0;
        
        for error in sorted_errors {
            if let Some(line) = error.line_number {
                if current_group.is_empty() || line.abs_diff(last_line as u32) <= proximity_threshold as u32 {
                    current_group.push(error);
                    last_line = line as usize;
                } else {
                    groups.push(current_group);
                    current_group = vec![error];
                    last_line = line as usize;
                }
            } else {
                // 没有行号的错误单独成组
                if !current_group.is_empty() {
                    groups.push(current_group);
                    current_group = Vec::new();
                }
                groups.push(vec![error]);
            }
        }
        
        if !current_group.is_empty() {
            groups.push(current_group);
        }
        
        groups
    }
}
